package com.flida.echart.core.order.service.impl;

import com.alibaba.fastjson.JSON;
import com.feilong.core.Validator;
import com.feilong.core.bean.BeanOperationException;
import com.flida.bana.common.util.DateUtils;
import com.flida.bana.common.util.GaodeHelper;
import com.flida.bana.common.util.GeoHash;
import com.flida.echart.basic.api.service.GateUserService;
import com.flida.echart.core.api.order.entity.CoreConstant;
import com.flida.echart.core.api.order.entity.Order;
import com.flida.echart.core.api.order.entity.OrderReq;
import com.flida.echart.core.api.order.entity.OrderTemplate;
import com.flida.echart.core.order.dao.OrderDao;
import com.flida.echart.core.order.service.IOrderService;
import com.flida.echart.core.order.service.IOrderTemplateService;
import com.flida.echart.core.utils.JRedisUtil;
import com.flida.echart.core.utils.RedisKeyUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.apache.log4j.Logger;
import org.dozer.DozerBeanMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * Created by yzc on 2016/12/11.
 */
@Service("orderService")
public class OrderServiceImpl implements IOrderService {

    private static Logger log4j = Logger.getLogger(OrderServiceImpl.class);
    @Value("${date.formate}")
    public String dateFormate;


    @Value("${order.rediskey.alive}")
    public int orAlive;//order key 存活时间
    @Value("${order.query.city}")
    public int queryCity;

    @Value("${order.query.ltude}")
    public int queryLtude;

    @Value("${order.pageSize}")
    public int pageSize;

    @Autowired
    public IOrderTemplateService orderTemplateService;
    @Resource
    DozerBeanMapper dozerMapperManager;
    @Autowired
    private JRedisUtil jredisUtil;
    @Autowired(required = false)
    private OrderDao orderDao;

    @Resource
    private GateUserService gateUserService;//调用echart-basic 服务

    public int deleteByPrimaryKey(String id) {
        return orderDao.deleteByPrimaryKey(id);
    }


    public int insert(Order record) {

        return orderDao.insert(record);
    }


    public int insertSelective(Order record) {
        return orderDao.insertSelective(record);
    }


    public Order selectByPrimaryKey(String id) {
        return orderDao.selectByPrimaryKey(id);
    }


    public int updateByPrimaryKeySelective(Order record) {
        return orderDao.updateByPrimaryKeySelective(record);
    }


    public int updateByPrimaryKey(Order record) {
        return orderDao.updateByPrimaryKey(record);
    }

    /**
     * 通过模板来添加Order 到mysql
     * @param userid 用户Id
     * @return
     */

    public int insertFromTemplateByUserid(String userid) {

        Validate.notBlank(userid, "userid [destination bean] not null!", new Object[0]);
        Order order = getOrderFromOrderTemplateByUserId(userid);
        Validate.notNull(order, "order [destination bean] not null!", new Object[0]);
        return insert(order);

    }
    /**
     * 通过用户Id  查询orderTemplate 然后组装成Order
     *
     * @param userid 用户Id
     * @return
     */
    private Order getOrderFromOrderTemplateByUserId(String userid) {

        Validate.notBlank(userid, "userid [destination bean] not null!", new Object[0]);
        OrderTemplate template=new OrderTemplate();
        template.setUserid(userid);
        template.setStatus(CoreConstant.OrderTemplate_status_0);//激活
        List<OrderTemplate> orderTemplateList = orderTemplateService.query(template);
        if(Validator.isNotNullOrEmpty(orderTemplateList)&&orderTemplateList.size()==1){
            Order order = new Order();
            dozer(order, orderTemplateList.get(0));//模板内容复制
            fillOrder(order);//Order初始值
            return order;
        }else{
            return null;
        }
    }


    private Order getOrderFromOrderTemplate(OrderTemplate orderTemplate) {

        Validate.notNull(orderTemplate, "orderTemplate [destination bean] not null!", new Object[0]);
        Order order = new Order();
        dozer(order,orderTemplate);//模板内容复制
        fillOrder(order);//Order初始值
        return order;
    }
    /**
     * 用户通过前端添加Order
     *
     * @param userid 用户Id
     * @param content order内容
     * @param latitude  经纬度
     * @return
     */
    private Order getOrderFromOrderTemplateByUserId(String userid,String content,Double latitude, Double longitude) {

      if(!StringUtils.isBlank(userid)&&!StringUtils.isBlank(content)){

      }
      return null;
    }


    private void dozer(Order order, OrderTemplate orderTemplate) {

        if (Validator.isNotNullOrEmpty(orderTemplate)) {
            if(Validator.isNullOrEmpty(order)){
                order = new Order();
            }
            try{
                dozerMapperManager.map(orderTemplate, order);
            }catch (Exception ex){
                throw new BeanOperationException(ex);
            }
        }
    }

    private void fillOrder(Order order) {
        if(Validator.isNotNullOrEmpty(order)){
            order.setDatetime(DateUtils.getNoTime(dateFormate));
            order.setStatus(CoreConstant.Order_insert_status_0);
        }
    }

    /**
     * 通过模板来添加Order 到redis
     * 添加    *
     * @param userid 用户Id
     * @return
     */

    public void insertOrderToRedisByUserid(String userid) {
        Validate.notBlank(userid, "userid [destination bean] not null!", new Object[0]);
        try{
            Order order = getOrderFromOrderTemplateByUserId(userid);
            Validate.notNull(order, "order [destination bean] not null!", new Object[0]);
            String redisKeyCity= RedisKeyUtils.getOrderKey(order);//按城市保存
            String redisKeyGeoHash=RedisKeyUtils.getGeoHashKey(order.getLatitude(),order.getLongitude());//按区域保存 geohash
            Validate.notBlank(redisKeyGeoHash, "redisKeyGeoHash [destination bean] not null!", new Object[0]);
            //保存city
            saveRedis(redisKeyCity,order);
            //保存附近
            saveRedis(redisKeyGeoHash,order);
        }catch (Exception ex){
            throw new BeanOperationException(ex);
        }
    }


    public void insertOrderToRedis(OrderTemplate orderTemplate) {
        Validate.notNull(orderTemplate, "orderTemplate [destination bean] not null!", new Object[0]);
        try{
            Order order =getOrderFromOrderTemplate(orderTemplate);
            Validate.notNull(order, "order [destination bean] not null!", new Object[0]);
            String redisKeyCity= RedisKeyUtils.getOrderKey(order);//按城市保存
            String redisKeyGeoHash=RedisKeyUtils.getGeoHashKey(order.getLatitude(),order.getLongitude());//按区域保存 geohash
            Validate.notBlank(redisKeyGeoHash, "redisKeyGeoHash [destination bean] not null!", new Object[0]);
            //保存city
            saveRedis(redisKeyCity,order);
            //保存附近
            saveRedis(redisKeyGeoHash,order);
        }catch (Exception ex){
            throw new BeanOperationException(ex);
        }
    }


    /**
     * 通过定时任务自动添加任务
     *
     * @return
     */
    public void autoAddOrderH() {

        //自动添加---黄金会员
        autoAddOrder(CoreConstant.OrderTemplate_leve_12);


    }

    public void autoAddOrderM() {

        //自动添加---vip
        autoAddOrder(CoreConstant.OrderTemplate_leve_11);

    }

    public void autoAddOrderL() {

        //自动添加---临时vip
        autoAddOrder(CoreConstant.OrderTemplate_leve_1);

    }

    public void autoAddOrder(int level) {

        OrderTemplate orderTemplate=new OrderTemplate();
        orderTemplate.setLevel(level);
        List<OrderTemplate> orderTemplateList=orderTemplateService.query(orderTemplate);
        if(Validator.isNotNullOrEmpty(orderTemplateList)){

            for(OrderTemplate  template:orderTemplateList){
                if(Validator.isNotNullOrEmpty(template)){
                    try{
                        insertOrderToRedis(template);
                    }catch (Exception ex){
                        log4j.error("order 添加到redis失败："+ex.getMessage()+template.toString());

                    }
                }

            }


        }
    }

    private void  saveRedis(String redisKey,Order order){
        Validate.notBlank(redisKey, "redisKey [destination bean] not null!", new Object[0]);
        if(Validator.isNotNullOrEmpty(order)){
            try{
                String orderJson=JSON.toJSONString(order);
                jredisUtil.zadd(redisKey,RedisKeyUtils.getOrderScore(),orderJson,orAlive);
            }catch (Exception ex){
                throw new BeanOperationException(ex);
            }

        }
    }

    public List<Order> queryOrder(OrderReq orderReq){
        Validate.notNull(orderReq, "orderReq [destination bean] not null!", new Object[0]);
        if(orderReq.getType()==queryCity){
            return  queryOrderFromCity(orderReq);
        }else if(orderReq.getType()==queryLtude){
            return  queryOrderFromNearby(orderReq);
        }else{
            throw new  RuntimeException("数据异常,不支持查询order方式,type值错误");
        }

    }

    private void validateOrderReq(OrderReq orderReq){
        Validate.notNull(orderReq, "orderReq [destination bean] not null!", new Object[0]);
        if(Validator.isNullOrEmpty(orderReq.getNumber())){
            orderReq.setNumber(0);
        }
        if(Validator.isNullOrEmpty(orderReq.getPageSize())){
            orderReq.setPageSize(pageSize);
        }
    }
    public List<Order> queryOrderFromCity(OrderReq orderReq){

        Validate.notNull(orderReq, "orderReq [destination bean] not null!", new Object[0]);
        Validate.notNull(orderReq.getCityid(), " orderReq.getCityid() [destination bean] not null!", new Object[0]);
        validateOrderReq(orderReq);
        try{
            Object data=jredisUtil.lrange(RedisKeyUtils.getOrderKey(orderReq.getCityid()), orderReq.getNumber(), orderReq.getPageSize());
            if(Validator.isNullOrEmpty(data)){
                return null;
            }else{
                return JSON.parseObject(data.toString(),List.class);
            }
        }catch (Exception ex){
            throw new BeanOperationException(ex);
        }
    }
    public List<Order> queryOrderFromNearby(OrderReq orderReq){
        List<Order> result=null;
        try{
            Validate.notNull(orderReq, "orderReq [destination bean] not null!", new Object[0]);
            Validate.notNull(orderReq.getCityid(), " orderReq.getCityid() [destination bean] not null!", new Object[0]);
            validateOrderReq(orderReq);
            double[]  gbs=new double[2];
            //如果有经纬度
            if(Validator.isNotNullOrEmpty(orderReq.getLatitude())&&Validator.isNotNullOrEmpty(orderReq.getLongitude())){
                gbs[0]=orderReq.getLongitude();
                gbs[1]=orderReq.getLatitude();
            }else{
                String  areaName=gateUserService.getAreaName(String.valueOf(orderReq.getCityid()));
                gbs=GaodeHelper.addressToGPS(areaName);
            }
            if(Validator.isNotNullOrEmpty(gbs)&&gbs.length==2){
                String geoHash=new GeoHash( gbs[1],gbs[0]).getGeoHashBase32();
                Object data=jredisUtil.lrange(geoHash, orderReq.getNumber(), orderReq.getPageSize());
                if(Validator.isNullOrEmpty(data)){
                    return null;
                }else{
                    result= JSON.parseObject(data.toString(),List.class);
                }
            }
        }catch (Exception ex){
            log4j.error("查询附近信息异常:"+ex.getMessage()+":orderReq="+orderReq.toString());
        }
        return  result;
    }

}
